<template>
	<!-- 组件外层容器 -->
	<focus-box position="relative" bg="info" bgscheme="light" :margin="margin" :radius="radius" @click="realImgClick">
		
		<!-- 要显示的图片 -->
		<image :style="styleImg" :src="src_img" :mode="mode_img" @load="imgLoadCall" @error="imgErrorCall"></image>
		
		<!-- 占位图容器 -->
		<focus-box v-if="isLoad==false"
		position="absolute" left="0" right="0" top="0" bottom="0"
		mode="row" justify="center" align="center" bg="info" bgscheme="light" :radius="radius">
			<!-- 占位图标 -->
			<focus-icon name="fi-img" :size="sizeHoldIcon" color="white"></focus-icon>
		</focus-box>
		
	</focus-box>
</template>


<script>
	// 盒子布局 组件引入
	import focusBox from '../focus-box/focus-box.vue';
	// 字体图标 组件引入
	import focusIcon from '../focus-icon/focus-icon.vue';
	
	/**
	 * 图片
	 * @description vue/nvue通用，媒体类组件，图片显示组件
	 * @tutorial
	 * @property {String} tag 组件自定义标识，默认：focus-img
	 * @property {String} src 图片资源地址
	 * @property {String} mode = [stretch|beyond|space|width|height] 图片的缩放、裁剪模式，默认：stretch
	 *   @value stretch 拉伸图片，使完全填满image元素
	 *   @value beyond 缩放图片，使完全填满image元素(会超出image范围)
	 *   @value space 缩放图片，使图片完整地显示在image内部(会存在空白区域)
	 *   @value width 宽度width固定，高度按照原图比例自动适应
	 *   @value height 高度height固定，宽度按照原图比例自动适应
	 * @property {String,Number,Array} size 容器宽高(rpx)，数组形式，写法：[50]/[100,50]
	 * @property {String,Number,Array} margin 容器外边距(rpx)，数组形式，写法：[24]/[12,24]/[12,0,12,24]
	 * @property {String,Number,Array} radius 边框圆角(rpx)，数组形式，写法：[10]/[8,10]/[8,10,12,24]
	 * @property {string,Boolean} preview = [false|true] 是否开启点击预览，默认：false
	 *   @value false 关闭预览功能
	 *   @value true 开启预览功能
	 * @event {Function} click 点击图片触发
	 */
	export default {
		name: "focus-img",
		// 传递数据
		props: {
			"tag": { type: String, default: 'focus-img' },
			"src": { type: String, default: '' },
			"mode": { type: String, default: 'stretch' },
			"size": { type: [String,Number,Array], default: null },
			"margin": { type: [String,Number,Array], default: null },
			"radius": { type: [String,Number,Array], default: null },
			"preview": { type: [String,Boolean], default: false }
		},
		
		// 组件定义
		components: {
			focusBox,
			focusIcon,
		},
		
		// 页面数据
		data() {
			return {
				// 状态信息
				isLoad: false, // 图片是否载入完毕
				// 临时资源
				path_preimg: '', // 预览图片临时资源地址
				// 配置信息
				width_img: 0, // 图片宽度(rpx)
				height_img: 0, // 图片高度(rpx)
				src_img: '', // 图片src属性
				mode_img: 'scaleToFill', // 图片显示模式
			}
		},
		
		// 计算属性
		computed: {
			// 真实图片style属性
			styleImg() {
				// 初始化
				var obj_style = {};
				var str_style = '';
				
				// ======================================= 容器宽高
				if (this.width_img > 0) { obj_style['width'] = this.width_img + 'rpx'; }
				if (this.height_img > 0) { obj_style['height'] = this.height_img + 'rpx'; }
				
				// ======================================= 边框圆角
				// 传入的是 string 和 number 的情况
				if ( (typeof(this.radius)=="string" || typeof(this.radius)=="number") && this.radius)
				{
					obj_style['border-radius'] = this.radius + 'rpx';
				}
				// 传入的是 array 的情况
				else if (typeof(this.radius)=="object" && this.radius && this.radius.length)
				{
					// 只有一个元素
					if (this.radius.length == 1)
					{
						obj_style['border-radius'] = this.radius[0] + 'rpx';
					}
					// 有2个元素
					else if (this.radius.length == 2)
					{
						obj_style['border-top-left-radius'] = this.radius[0] + 'rpx';
						obj_style['border-top-right-radius'] = this.radius[1] + 'rpx';
						obj_style['border-bottom-right-radius'] = this.radius[0] + 'rpx';
						obj_style['border-bottom-left-radius'] = this.radius[1] + 'rpx';
					}
					// 有4个元素及以上
					else if (this.radius.length >= 4)
					{
						obj_style['border-top-left-radius'] = this.radius[0] + 'rpx';
						obj_style['border-top-right-radius'] = this.radius[1] + 'rpx';
						obj_style['border-bottom-right-radius'] = this.radius[2] + 'rpx';
						obj_style['border-bottom-left-radius'] = this.radius[3] + 'rpx';
					}
				}
				
				// 循环样式对象
				for (let k in obj_style) { str_style += k + ':' + obj_style[k] + ';'; }
				// 结果返回
				return str_style;
			},
			// 占位图标字体大小
			sizeHoldIcon() {
				
				// 真实图片宽高
				var width_realimg = this.width_img;
				var height_realimg = this.height_img;
				
				// 计算占位图标的大小
				var size_icon_placeholder = width_realimg;
				// 比较真实图片的宽高
				if (width_realimg > height_realimg) { size_icon_placeholder = height_realimg; }
				// 限制图标大小为<=130
				if (size_icon_placeholder > 130) { size_icon_placeholder = 130; }
				
				// 结果返回
				return size_icon_placeholder;
			},
		},
		
		// 数据监听
		watch: {
			// 图片资源地址
			src: {
				handler(newValue, oldValue) {
					// 图片渲染内存优化处理
					this.imgDrawingOptimize();
				},
				immediate: true
			},
			// 容器宽高
			size: {
				handler(newValue, oldValue) {
					// 传入的是 string 和 number 的情况
					if ( (typeof(newValue)=="string" || typeof(newValue)=="number") && newValue)
					{
						this.width_img = newValue;
						this.height_img = newValue;
					}
					// 传入的是 array 的情况
					else if (typeof(newValue)=="object" && newValue && newValue.length)
					{
						// 只有一个元素
						if (newValue.length == 1)
						{
							this.width_img = newValue[0];
							this.height_img = newValue[0];
						}
						// 有2个元素
						else if (newValue.length == 2)
						{
							this.width_img = newValue[0];
							this.height_img = newValue[1];
						}
					}
				},
				immediate: true
			},
			// 图片的缩放、裁剪模式
			mode: {
				handler(newValue, oldValue) {
					if (newValue == 'beyond') { this.mode_img = 'aspectFill'; }
					else if (newValue == 'space') { this.mode_img = 'aspectFit'; }
					else if (newValue == 'width') { this.mode_img = 'widthFix'; }
					else if (newValue == 'height') { this.mode_img = 'heightFix'; }
					else { this.mode_img = 'scaleToFill'; }
				},
				immediate: true
			},
		},
		
		// 组件事件
		methods: {
			
			// ==================================== 数据处理
			// 图片渲染内存优化处理
			imgDrawingOptimize() {
				// 获取图片信息
				uni.getImageInfo({
					src: this.src,
					fail: () => {
						// 分析失败，只能让原图显示了
						this.src_img = this.src;
						// 预览图片临时资源地址也等于原图
						this.path_preimg = this.src;
					},
					success: (image_original) => {
						
						// 预览图片临时资源地址 = 分析后的临时路径
						this.path_preimg = image_original.path;
						
						// 组件图片宽高单位转化为px
						var width_px = uni.upx2px(this.width_img);
						var height_px = uni.upx2px(this.height_img);
						// 如果原始图片大小 大于了 设定大小
						if (image_original.width > width_px || image_original.height > height_px)
						{
							// 对图片进行压缩
							uni.compressImage({
								src: image_original.path, // 使用分析后的临时路径
								width: this.width_img + 'px', // 设置为组件宽度
								height: 'auto', // 高度自适应
								fail: () => {
									// 压缩失败，只能渲染临时路径了
									this.src_img = image_original.path;
								},
								success: (image_compress) => {
									// 让组件img渲染压缩后的图片
									this.src_img = image_compress.tempFilePath;
								},
							});
						}
						
						// 说明原图已经很小了，直接渲染临时路径
						else { this.src_img = image_original.path; }
						
					}
				});
			},
			
			// 图片载入完成 回调
			imgLoadCall() {
				// 标记为"载入完成"
				this.isLoad = true;
			},
			// 图片载入失败 回调
			imgErrorCall() {
				// 标记为"载入失败"
				this.isLoad = false;
			},
			
			
			// ==================================== 元素事件
			// 真实图片 点击
			realImgClick() {
				// 如果开启了图片预览
				if ( (this.preview=='true'||this.preview==true) && this.isLoad==true )
				{
					// uni预览图片API
					uni.previewImage({
						urls: [this.path_preimg],
						current: 0,
					});
				}
				// 图片点击触发回调事件
				this.$emit('click', { "tag": this.tag });
			},
			
		}
		
	}
</script>